package cn.tedu.map;

import java.util.*;

/*本类用于测试Map接口*/
public class MapDemo {
    public static void main(String[] args) {
        //1.创建Map对象
        /*Map中的数据要符合映射规则,一定注意要同时指定K和V的数据类型
         * 至于这个K和V具体要设置成什么类型,取决于具体的业务需求*/
        Map<Integer,String> map = new HashMap<>();  //K,V泛型,代表HashMap的具体引用类型
        //2.向map集合存入数据,注意方法是put并且需要存入一对<K,V>的值
        map.put(9528,"null");
        map.put(9526,null);
        map.put(9527,"白骨精");
        map.put(9529,"鲤鱼精");
        map.put(9531,"黑熊精");
        map.put(9530,"黄毛怪");
        map.put(9527,"女儿国国王");
//        map.put(9526,"灯芯妖");
        /*1.Map中的key不允许重复,如果重复,后面的value会把前面的value覆盖掉
         * 比如:女儿国国王和白骨精的key都是9527,白骨精就被覆盖掉了
         * 2.Map中的value可以重复,比如我们有两个黑熊精*/
        System.out.println(map); //{9527=女儿国国王, 9528=黑熊精, 9529=鲤鱼精, 9530=黄毛怪, 9531=黑熊精} //覆盖顶替第一个元素的值

        //3.进行方法测试
//        map.clear();//清空集合
//        System.out.println(map);//{}
        System.out.println(map.isEmpty());//false,判断集合是否为空
        System.out.println(map.size());//5,获取集合中键值对的对数
        System.out.println(map.containsKey(9527));//true,判断集合是否包含指定的键
        System.out.println(map.containsValue("白骨精"));//false,判断集合是否包含指定的值
        System.out.println(map.remove(9529));//根据key删除对应的这一对键值对,K与V都删了
        System.out.println(map); //{9527=女儿国国王, 9528=黑熊精, 9530=黄毛怪, 9531=黑熊精}
        System.out.println(map.containsKey(9529));
        System.out.println(map.containsValue("鲤鱼精"));

        Collection<String> c = map.values();//将map中所有的value值取出,存入Collection中 //源码返回和创建了new collection, 通过传元素进去//感知后,会用先
        System.out.println(c);//[女儿国国王, 黑熊精, 黄毛怪, 黑熊精] //集合Collection底层重写的toString,打印集合的内容


        //4.map集合的迭代方式1
        /*方式1:
         * 遍历map中的数据,但是map本身没有迭代器,所以需要先转换成set集合
         * 用到的方法:keySet():把map中的所有key值存入到set集合中Set<Key>
         */
        //4.1将map集合的所有key值取出,存入Set集合中,Set集合的泛型就是key的类型
        Set<Integer> set = map.keySet();
        System.out.println("打印Set:" + set);
        //4.2迭代set集合,首先获取迭代器
        Iterator<Integer> it = set.iterator();
        //4.3循环,判断是否有下一个元素可以迭代
        while(it.hasNext()){
            //4.4获取本轮循环到的元素,就是set中存的每个key
            Integer key = it.next(); //map集合无法一个一个获取元素,只能通过keySet()一次性获取所有map的键的元素,存入set对象,然后再创建set的迭代器和遍历Set迭代器
            //4.5根据key获取map中对应的value (先获取key,在获取value值)
            String value = map.get(key);
            System.out.println("{"+key+","+value+"}");//拼接打印,拼接打印,拼接打印,拼接打印
        }
        //PS: map->set->Iterator->map key-> map value

        /*方式2:
         * 遍历map集合,需要把map集合先转成set集合
         * 是把map中的一对键值对key&value作为一个Entry<K,V>整体放入set
         * 一对K,V就是一个Entry*/
        Set<Map.Entry<Integer, String>> set2 = map.entrySet(); //存的entry对象              //静态内部类队形创建: Outer3.Inner3 oi = new Outer3.Inner3();//Inner3()是无参构造
//        Set<Map.Entry<Integer, String>> entries = map.entrySet();

        //     Set<Integer> set = map.keySet();
        //通过HahMap的entrySet()方法,返回KV键值对的嵌套泛型结构:     Map.Entry<Integer, String>
        Iterator<Map.Entry<Integer, String>> it2 = set2.iterator(); //泛型的嵌套//包含了Set集合对象set2的迭代对象
        while(it2.hasNext()){
            //Outer1.Entry aaa = new Outer1().new Entry(); //通过嵌套两个类(内部类和外部类方式),配合泛型,创建获取迭代器当前元素entry的KV对象
            Map.Entry<Integer, String> entry = it2.next(); //Map.Entry<Integer, String>内部类的对象,用来存放KV键值对的嵌套类型,,相当于单个键的数据类型,包装类型Integer

//            Map.Entry<Integer, String> entry1 = it2.next();
            System.out.println(entry);//直接打印本轮循环到的entry可以直接查看<K,V>
            Integer key = entry.getKey();//单独获取本entry中的key值
            String value = entry.getValue();//单独获取本entry中的value值
            System.out.println(key+"!!!"+value);
        }
    }
}







